<?php
namespace app\model\mongo\traits;

use const support\ARRAYDATA;
use const support\FLOAT;
use const support\INT;
use const support\LIMIT;
use const support\PAGE;
use const support\STRING;

trait MongoMethod{

    //字段数据类型转换
    protected static function setDataTypeConversion(array $data): array
    {
        if (empty($data)){
            return [];
        }
        //获取支持的字段
        $supportFields=self::$fields;
        if (empty($supportFields)){
            return $data;
        }
        $keys=array_keys($supportFields);
        $document=[];
        foreach ($supportFields as $field=>$type){
            if (!in_array($field,$keys)){
                continue;
            }
            if ($type==STRING){
                $document[$field]=(string)($data[$field]??'');
            }elseif ($type==INT){
                $document[$field]=(int)($data[$field]??0);
            }elseif ($type==FLOAT){
                $document[$field]=(float)($data[$field]??0);
            }elseif ($type==ARRAYDATA){
                $document[$field]=(array)($data[$field]??[]);
            }
        }
        return $document;
    }

    //新增入库
    protected static function insertOne(array $data): bool
    {
        //进行数据转换
        $document=self::setDataTypeConversion($data);
        if ($document){
            $document[self::CREATED_AT]=time();
            $document[self::UPDATED_AT]=time();
        }else{
            return false;
        }
        return self::insert($document);
    }

    //更新数据
    protected static function updateData(array $queryData, array $updateData): bool
    {
        $updateData[self::UPDATED_AT]=time();
        return self::where($queryData)->update($updateData);
    }

    //批量添加数据
    protected static function insertMore(array $inserts): bool
    {
        //进行数据转换
        $insertAll=[];
        foreach ($inserts as $insert){
            $document=self::setDataTypeConversion($insert);
            if ($document){
                $document[self::CREATED_AT]=(int)time();
                $document[self::UPDATED_AT]=(int)time();
            }else{
                return false;
            }
            $insertAll[]=$document;
        }
        return self::insert($insertAll);
    }

    //查询多条数据
    protected static function selectMore(array $where=[],array $order=[],int $page=PAGE,int $limit=LIMIT,array $fields=[]): array
    {
        $model=self::where($where);
        if ($order){
            list($orderByField,$orderBy)=$order;
            $model=$model->orderBy($orderByField,$orderBy);
        }
        if (!empty($fields)){
            $model=$model->select($fields);
        }
        $lists=$model->offset(($page-1)*$limit)->limit($limit)->get()->toArray();
        if (empty($lists)){
            return [];
        }
        return array_map(function ($item) use($fields){
            $item['id']=$item['_id']??'';
            unset($item['_id']);
            return $item;
        },$lists);
    }

    //查询一列数据
    protected static function selectColumn($column,array $where=[],array $order=[]): array
    {
        $model=self::where($where);
        if ($order){
            list($orderByField,$orderBy)=$order;
            $model=$model->orderBy($orderByField,$orderBy);
        }
        return $model->pluck($column)->toArray()?:[];
    }

    //查询数量
    protected static function selectMoreCount($where=[]): int
    {
        return self::where($where)->count()?:0;
    }

    //查询单条记录
    protected static function selectOne(array $where=[],array $fields=[]): array
    {
        $model=self::where($where);
        if (!empty($fields)){
            $model=$model->select($fields);
        }
        $model=$model->first();
        if (empty($model->_id)){
            return [];
        }
        $data=$model->toArray();
        $data['id']=$data['_id']??'';
        unset($data['_id']);
        return $data;
    }

    /**
     * 随机获取数据
     * @param array $where
     * @param int $num
     * @param array $fields
     * @return mixed
     */
    protected static function selectRandomMore(array $where,int $num=1,array $fields=[]){
        //数组求交集
        $keys=array_keys(self::$fields);
        $fields=!empty($fields)?array_intersect($keys,$fields):$keys;
        //整理查询格式
        $searchFields=['_id'=>1];
        foreach ($fields as $field){
            $searchFields[$field]=1;
        }
        $lists= self::raw(function ($collection)use($where,$num,$searchFields){
            return $collection->aggregate([
                [
                    '$match' =>$where
                ],
                [
                    '$sample'=>['size'=>$num]
                ],
                [
                    '$project'=>$searchFields
                ]
            ]);
        })->toArray();
        foreach ($lists as &$list){
            $list['id']=$list['_id']??'';
            unset($list['_id']);
        }
        return $lists;
    }

}